<template>
  <div>
    <el-dialog v-model="dialogVisible" class="c-dialog-fixed" width="800px" :append-to-body="inDialog" :title="title"
      @closed="handleClosed" @close="handleClose">
      <el-form ref="formRef" label-width="auto" :model="formData" :rules="formRules" v-loading="loading">
        <el-divider>菜单信息</el-divider>
        <el-form-item label="菜单名称" prop="name">
          <el-input v-model="formData.name" placeholder="填写菜单名称"></el-input>
        </el-form-item>
        <el-form-item label="路径值" prop="path">
          <el-input v-model="formData.path" placeholder="填写路径值" style="width:200px"></el-input>
          <span class="c-text-grey c-text-xs c-mg-l-5p">* 会与该菜单的所有上级菜单的路径值拼接成完整路径</span>
        </el-form-item>
        <el-form-item label="排序值" prop="order">
          <el-input-number v-model="formData.order" controls-position="right"></el-input-number>
          <span class="c-text-grey c-text-xs c-mg-l-5p">* 值越小排得越前</span>
        </el-form-item>
        <el-form-item label="上级菜单" prop="parentId">
          <c-input-select :options="parentMenuOptions" v-model="formData.parentId"
            @click="handleOpenParentMenuDialog" />
        </el-form-item>
        <el-form-item label="多开页面" prop="canMultipleOpen">
          <el-switch v-model="formData.canMultipleOpen"></el-switch>
          <span class="c-text-grey c-text-xs c-mg-l-5p">* 在页面标签模式下，页面是否会根据参数的不同打开多个页面</span>
        </el-form-item>
        <el-form-item label="子页面" prop="isPage">
          <el-switch v-model="formData.isPage"></el-switch>
          <span class="c-text-grey c-text-xs c-mg-l-5p">* 是否为子页面，不显示在菜单列表中，仅能在底层菜单下级创建，权限验证由上级菜单决定</span>
        </el-form-item>
        <div v-show="!formData.isPage">
          <el-form-item label="菜单图标" prop="icon">
            <el-input v-model="formData.icon" style="width:200px" placeholder="填写图标类名"></el-input>
            <span class="c-text-grey c-text-xs c-mg-l-5p">
              * 图标预览：
              <el-icon>
                <component :is="formData.icon ?? systemStore.config.get('MENU_DEFAULT_ICON')" />
              </el-icon>
            </span>
          </el-form-item>
          <el-form-item label="菜单接口" prop="apis">
            <div class="c-mg-b-5p">
              <el-button type="primary" @click="openApiDialog()">添加</el-button>
              <el-button @click="removeApis">删除</el-button>
              <span class="c-text-grey c-text-xs c-mg-l-10p">* 拥有菜单的访问权限，就拥有以下接口访问权限。</span>
            </div>
            <el-table ref="apiListRef" :border="false" :data="formData.apis">
              <el-table-column type="selection" width="35" align="center" />
              <el-table-column label="接口名称" prop="name" min-width="100" show-overflow-tooltip></el-table-column>
              <el-table-column label="接口路径" prop="path" min-width="150" show-overflow-tooltip></el-table-column>
            </el-table>
          </el-form-item>
          <el-form-item label="菜单权限" prop="permissions">
            <div class="c-mg-b-5p">
              <el-button type="primary" @click="openPermissionDialog">添加</el-button>
              <el-button @click="removePermissions">删除</el-button>
              <span class="c-text-grey c-text-xs c-mg-l-10p">* 拥有菜单的对应权限，就拥有对应权限接口访问权限。</span>
            </div>
            <el-table ref="permissionListRef" :border="false" :data="formData.permissions">
              <el-table-column type="selection" width="35" align="center"></el-table-column>
              <el-table-column label="权限值" prop="code" width="100"></el-table-column>
              <el-table-column label="权限名" prop="name" width="100"></el-table-column>
              <el-table-column label="排序" prop="order" align="center" width="80"></el-table-column>
              <el-table-column label="接口">
                <template #default="{ row }">
                  <div v-for="a in row.apis" :key="a.apiId">
                    {{ a.name }} [{{ a.path }}]
                  </div>
                </template>
              </el-table-column>
              <el-table-column label="操作" width="60" align="center">
                <template #default="{ row }">
                  <el-button type="text" icon="el-icon-edit" @click="openEditPermission(row)" />
                </template>
              </el-table-column>
            </el-table>
          </el-form-item>
        </div>
      </el-form>
      <template #footer>
        <el-button type="primary" @click="save" :loading="loading">保存</el-button>
      </template>
    </el-dialog>
    <el-dialog v-model="permissionDialogVisible" class="c-dialog-fixed" :append-to-body="inDialog" width="600px"
      title="菜单权限" ref="permissionDialogRef" @open="handlePermissionDialogOpen" @closed="handlePermissionDialogClosed">
      <el-form ref="permissionFormRef" label-width="auto" :model="permissionFormData" :rules="permissionFormRules">
        <el-divider>权限信息</el-divider>
        <el-form-item label="权限值" prop="code">
          <el-input placeholder="权限值，同一个菜单里必须唯一" v-model="permissionFormData.code" />
        </el-form-item>
        <el-form-item label="权限名称" prop="name">
          <el-input placeholder="权限名称，尽量不超出4个字符" v-model="permissionFormData.name" />
        </el-form-item>
        <el-form-item label="排序值" prop="order">
          <el-input-number v-model="permissionFormData.order" controls-position="right"></el-input-number>
          <span class="c-text-grey c-text-xs c-mg-l-5p">* 值越小排得越前</span>
        </el-form-item>
        <el-form-item label="权限接口" prop="apis">
          <div class="c-mg-b-5p">
            <el-button type="primary" @click="openApiDialog('permissionApi')">添加</el-button>
            <el-button @click="removePermissionApis">删除</el-button>
          </div>
          <el-table ref="permissionApiListRef" :border="false" :data="permissionFormData.apis">
            <el-table-column type="selection" width="35" align="center"></el-table-column>
            <el-table-column label="接口名称" prop="name" min-width="100" show-overflow-tooltip></el-table-column>
            <el-table-column label="接口路径" prop="path" min-width="150" show-overflow-tooltip></el-table-column>
          </el-table>
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button type="primary" @click="savePermission">保存</el-button>
      </template>
    </el-dialog>
    <menu-dialog ref="parentMenuDialogRef" single-select @select="handleParentMenuSelect" />
    <api-dialog ref="apiDialogRef" multiple-select @select="handleApiSelect" />
  </div>
</template>
<script setup>
import menuApi from "@/api/sys/menu";
import { ref, useTemplateRef } from "vue";
import { toTreeData, cloneDeepObject, cloneObjectValue } from "@/utils/common"
import { ElMessage } from "element-plus";
import { useSystemStore } from "@/stores";
import menuDialog from "./listDialog.vue";
import apiDialog from "@/components/sys/api/listDialog.vue";

const props = defineProps({
  inDialog: {
    type: Boolean,
    default: false
  }
})
const systemStore = useSystemStore();
const title = ref("")
const formData = ref({
  id: 0,
  parentId: null,
  name: "",
  path: "",
  icon: "",
  parentName: "",
  canMultipleOpen: false,
  isPage: false,
  order: 99,
  hasRead: false,
  hasWrite: false,
  hasReview: false,
  apis: [],
  permissions: []
})
const saved = ref(false)
const loading = ref(false)
const dialogVisible = ref(false)
const permissionDialogVisible = ref(false)
const parentMenuDialogRef = useTemplateRef("parentMenuDialogRef")
const apiDialogRef = useTemplateRef("apiDialogRef")
const apiListRef = useTemplateRef("apiListRef")
const permissionListRef = useTemplateRef("permissionListRef")
const permissionApiListRef = useTemplateRef("permissionApiListRef")
const permissionFormRef = useTemplateRef("permissionFormRef")
const apiDialogType = ref("api")
const parentMenuOptions = ref([])
const editPermissionFormData = ref(null)

const formRules = ref({
  name: [{ required: true, message: "请填写菜单名称" }],
  path: [{ required: true, message: "请填写菜单路径值" }],
  order: [{ required: true, message: "请填写菜单排序值" }]
})


const permissionFormData = ref({
  code: "",
  name: "",
  apis: [],
  order: 99
})
const permissionFormRules = ref({
  code: [{ required: true, message: "请填写权限值" }],
  name: [{ required: true, message: "请填写权限名称" }],
})
const emits = defineEmits(["close-saved"])

const formRef = useTemplateRef("formRef")
const openCreate = async (parentMenu = null) => {
  title.value = "创建菜单";
  dialogVisible.value = true
  if (parentMenu != null) {
    formData.value.parentId = parentMenu.id
    formData.value.parentName = parentMenu.name
    parentMenuOptions.value = [
      {
        id: parentMenu.id,
        name: parentMenu.name
      }
    ]
  }
  loading.value = true
  loading.value = false
}
const openEditById = async (id) => {
  title.value = "编辑菜单";
  dialogVisible.value = true
  loading.value = true;
  const res = await menuApi.getEditById(id)
  formData.value = res.data;
  if (formData.value.parentId) {
    parentMenuOptions.value = [
      {
        id: formData.value.parentId,
        name: formData.value.parentName
      }
    ]
  }
  loading.value = false;
}
//窗口关闭后事件
const handleClose = () => {
  if (saved.value) {
    emits("close-saved");
  }
}
//窗口关闭后事件
const handleClosed = () => {
  title.value = "";
  saved.value = false;
  formRef.value.resetFields();
}

//打开上级菜单窗口事件
const handleOpenParentMenuDialog = () => {
  console.log("parentMenuOptions", parentMenuOptions.value)
  parentMenuDialogRef.value.open(parentMenuOptions.value)
}

//保存
const save = async () => {
  loading.value = true;
  try {
    await formRef.value.validate();
  } catch {
    loading.value = false
    return
  }
  const saveData = {
    ...formData.value,
    apis: undefined,
    apiIds: formData.value.apis.map(i => i.id),
    permissions: formData.value.permissions.map(i => {
      return {
        code: i.code,
        name: i.name,
        order: i.order,
        apiIds: i.apis.map(i2 => i2.id)
      }
    })
  }
  const res = await menuApi.save(saveData);
  loading.value = false;
  if (res.code != 0) {
    return;
  }
  formData.value.id = res.data;
  saved.value = true;
  ElMessage.success("保存成功");
}
//上级菜单选择事件
const handleParentMenuSelect = (rows) => {
  formData.value.parentId = rows.find(i => true)?.id
  parentMenuOptions.value = [...rows]
}

//显示接口窗口
const openApiDialog = (type = "api") => {
  apiDialogType.value = type;
  let apis = null;
  if (type == "api") {
    apis = formData.value.apis;

  } else if (type == "permissionApi") {
    apis = permissionFormData.value.apis;
  }
  apiDialogRef.value.open(apis);
}
//接口窗口选择后事件
const handleApiSelect = (rows) => {
  if (apiDialogType.value == "api") {
    formData.value.apis = rows
  } else if (apiDialogType.value == "permissionApi") {
    permissionFormData.value.apis = rows
  }
}
//删除菜单接口
const removeApis = () => {
  const rows = apiListRef.value.getSelectionRows();
  for (let row of rows) {
    const index = formData.value.apis.indexOf(row);
    if (index < 0) {
      continue;
    }
    formData.value.apis.splice(index, 1)
  }
}

//删除权限
const removePermissions = () => {
  const rows = permissionListRef.value.getSelectionRows();
  for (let row of rows) {
    const index = formData.value.permissions.indexOf(row);
    if (index < 0) {
      continue;
    }
    formData.value.permissions.splice(index, 1)
  }
}
//删除权限接口
const removePermissionApis = () => {
  const rows = permissionApiListRef.value.getSelectionRows();
  for (let row of rows) {
    const index = permissionFormData.value.apis.indexOf(row);
    if (index < 0) {
      continue;
    }
    permissionFormData.value.apis.splice(index, 1)
  }
}

//打开权限窗口
const openPermissionDialog = () => {
  permissionDialogVisible.value = true
}

const handlePermissionDialogClosed = () => {
  editPermissionFormData.value = null
  permissionFormRef.value.resetFields()
}

const savePermission = async () => {
  try {
    await permissionFormRef.value.validate()
  } catch {
    return;
  }

  if (editPermissionFormData.value) {
    cloneObjectValue(editPermissionFormData.value, permissionFormData.value)
  } else {
    formData.value.permissions.push(cloneDeepObject(permissionFormData.value));
  }
  permissionDialogVisible.value = false
}
//显示权限编辑窗口
const openEditPermission = (row) => {
  editPermissionFormData.value = row;
  permissionDialogVisible.value = true

}

const handlePermissionDialogOpen = () => {
  if (editPermissionFormData.value) {
    cloneObjectValue(permissionFormData.value, editPermissionFormData.value)
  }
}

defineExpose({
  openCreate,
  openEditById
})
</script>